package de.hs_zigr.inf.iib08gruppe5powerfish.it;

import java.io.*;
import java.io.FileWriter;
import java.io.BufferedWriter;
import java.io.IOException;

import java.awt.event.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.event.*;
import java.awt.*;
import javax.swing.JTextArea;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JPasswordField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JDialog;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;

import org.xmldb.api.DatabaseManager;

import org.xmldb.api.base.Collection;
import org.xmldb.api.base.Database;
import org.xmldb.api.base.ResourceSet;
import org.xmldb.api.base.Resource;
import org.xmldb.api.base.ResourceIterator;
import org.xmldb.api.base.XMLDBException;
import org.xmldb.api.modules.BinaryResource;
import org.xmldb.api.modules.XMLResource;
import org.xmldb.api.modules.XPathQueryService;
import org.xmldb.api.modules.CollectionManagementService;
import org.xmldb.api.modules.XUpdateQueryService;
import org.xmldb.api.modules.XQueryService;

public class xmlUploader extends JFrame implements ActionListener,
		CaretListener {

	private JPanel jContentPane = null;

	private JButton fileChooser = null;
	private JButton uploadFile = null;
	private JButton query = null;
	private JButton newFile = null;
	private JButton speichern = null;
	private JButton delete = null;

	private String pathname, pfadname = "";

	private String filename, dateiname = "";

	private String dburi = null;

	private String collection = null;

	private Database database = null;

	private JLabel fileLabel = null;

	private JTextArea ta = null, sTa = null;
	private FileWriter fw;
	private BufferedWriter bw;
	public File datei;
	public String text = "";

	public void actionPerformed(ActionEvent evt) {
		Object source = evt.getSource();
		if (source.equals(fileChooser)) {
			JFileChooser chooser = new JFileChooser();
			chooser.setCurrentDirectory(new File("."));

			chooser.setFileFilter(new javax.swing.filechooser.FileFilter() {
				public boolean accept(File f) {
					return f.getName().toLowerCase().endsWith(".xml")
							|| f.isDirectory();
				}

				public String getDescription() {
					return "XML Dokumente";
				}
			});

			int r = chooser.showOpenDialog(this);
			if (r == JFileChooser.APPROVE_OPTION) {
				this.filename = chooser.getSelectedFile().getName();
				this.pathname = chooser.getSelectedFile().getAbsolutePath();

				fileLabel.setText(this.filename);

				uploadFile.setEnabled(true);
			}
		} else if (source.equals(uploadFile)) {
			// upload Datei
			dburi = (this.dburi != null) ? this.dburi : JOptionPane
					.showInputDialog(this,
							"Bitte den Datenbank Server und Port eingeben:",
							"localhost:8080");
			collection = (this.collection != null) ? this.collection
					: JOptionPane.showInputDialog(this,
							"Bitte die Collection eingeben:", "/xml");
			try {
				Collection col = this.openCollection(); // Zugriff zur
														// DB-Collection
														// verschaffen
				File f = new File(this.pathname);
				this.uploadXML(col, f); // XML-Datei hochladen
				JOptionPane.showMessageDialog(this,
						"Der Upload des XML-Dokumentes " + this.filename
								+ " war erfolgreich!", "Upload beendet",
						JOptionPane.INFORMATION_MESSAGE);
			} catch (XMLDBException e) {
				JOptionPane.showMessageDialog(this,
						"Der Upload des XML-Dokumentes " + this.filename
								+ " war fehlerhaft!\n" + e.getMessage(),
						"Upload beendet", JOptionPane.ERROR_MESSAGE);
			}

		} else if (source.equals(query)) { // Abfrage
			try {

				anfrageQuery(text);
			} catch (XMLDBException ex) {
				Logger.getLogger(xmlUploader.class.getName()).log(Level.SEVERE,
						null, ex);
			}

		} else if (source.equals(newFile)) { // Neue Datei erstellen
			String ext = ".xml";
			String file = JOptionPane.showInputDialog(
					"Bitte den Dateinamen eingeben", "NeueDatei");
			file = file.concat(ext);

			File f = new File(file); // ins aktuelle Pfad

			try {

				fw = new FileWriter(f);

				bw = new BufferedWriter(fw);
				String newline;
				newline = System.getProperty("line.separator");

				bw
						.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
								+ newline);
				bw.close();
			} catch (IOException ex) {
				Logger.getLogger(xmlUploader.class.getName()).log(Level.SEVERE,
						null, ex);
			}

		} else if (source.equals(speichern)) {
			JFileChooser dateiChooser = new JFileChooser();
			dateiChooser.setCurrentDirectory(new File("."));
			dateiChooser.setDialogType(JFileChooser.SAVE_DIALOG);

			dateiChooser
					.setFileFilter(new javax.swing.filechooser.FileFilter() {
						public boolean accept(File datei) {
							return datei.getName().toLowerCase().endsWith(
									".xml")
									|| datei.isDirectory();
						}

						public String getDescription() {
							return "XML Dokumente";
						}
					});
			int d = dateiChooser.showSaveDialog(this);
			if (d == JFileChooser.APPROVE_OPTION) {
				this.dateiname = dateiChooser.getSelectedFile().getName();
				this.pfadname = dateiChooser.getSelectedFile()
						.getAbsolutePath();

				fileLabel.setText(this.dateiname);
				// Anfrage in xml-datei speichern
				try {
					BufferedWriter bww = new BufferedWriter(new FileWriter(
							dateiChooser.getSelectedFile(), true)); // true:
																	// append
					String[] tab = sTa.getText().split("\n");

					for (String i : tab) {
						bww.append(i);
						bww.newLine();
					}
					bww.close();

				} catch (IOException e1) {
					System.out
							.println("Datei kann nicht zum Schreiben geöffnet werden");
					e1.printStackTrace();
				}

			} else {
				System.out.println("Abgebrochen");
			}

		} else if (source.equals(delete)) {
			sTa.setText("");
		}
	}

	// -----------Main---------------------------------------------------------------

	public static void main(String[] args) {
		JFrame uploader = new xmlUploader();
		uploader.setVisible(true);
	}

	// -----------Konstruktor--------------------------------------------------------
	public xmlUploader() {
		super();
		this.setLocationByPlatform(true);
		initialize();
	}

	// -----------Elemente der
	// GUI---------------------------------------------------
	private JLabel getFileLabel() {
		if (fileLabel == null) {
			fileLabel = new JLabel();
			fileLabel
					.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
			fileLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
			fileLabel.setEnabled(true);
		}
		return fileLabel;
	}

	private JButton getQuery() {
		if (query == null) {
			query = new JButton();
			query.setText("Query-Anfrage");
			query.setEnabled(true);
			query.addActionListener(this);
		}
		return query;
	}

	private JButton getSpeichern() {
		if (speichern == null) {
			speichern = new JButton();
			speichern.setText("Ergebnis speichern");
			speichern.setEnabled(false);
			speichern.addActionListener(this);
		}
		return speichern;
	}

	private JButton getDelete() {
		if (delete == null) {
			delete = new JButton();
			delete.setText("Löschen");
			delete.setEnabled(true);
			delete.addActionListener(this);
		}
		return delete;
	}

	private JButton getFileChooser() {
		if (fileChooser == null) {
			fileChooser = new JButton();
			fileChooser.setText("XML-Dokument von der Festplatte laden");
			fileChooser.addActionListener(this);
		}
		return fileChooser;
	}

	private JButton getUploadFile() {
		if (uploadFile == null) {
			uploadFile = new JButton();
			uploadFile.setText("XML-Dokument auf Server laden");
			uploadFile.setEnabled(false);
			uploadFile.addActionListener(this);
		}
		return uploadFile;
	}

	private JButton getNewFile() {
		if (newFile == null) {
			newFile = new JButton();
			newFile.setText("Leere XML-Datei erstellen");
			newFile.setEnabled(true);
			newFile.addActionListener(this);
		}
		return newFile;
	}

	private JTextArea getTextArea() {
		if (ta == null) {
			ta = new JTextArea(10, 40);
			ta.setEnabled(true);
			ta.addCaretListener(this);
		}
		return ta;
	}

	private JTextArea getSecondTextArea() {
		if (sTa == null) {
			sTa = new JTextArea(10, 40);
			sTa.setEnabled(true);
			sTa.addCaretListener(this);
		}
		return sTa;
	}

	// -------Initialisierung der
	// GUI------------------------------------------------

	private void initialize() {
		this.setSize(700, 500);
		this.setPreferredSize(new java.awt.Dimension(400, 400));
		this.setContentPane(getJContentPane());
		this.setTitle("XML-Document Uploader");
		this.addWindowListener(new java.awt.event.WindowAdapter() {
			@Override
			public void windowClosing(java.awt.event.WindowEvent e) {
				System.exit(0);
			}
		});
	}

	// ------------------------------------------------------------------------------
	/**
	 * diese Methode initialisiert jContentPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJContentPane() {
		if (jContentPane == null) {

			Panel panel1 = new Panel();
			panel1.setLayout(new GridLayout(3, 2));
			Panel panel2 = new Panel();
			panel2.setLayout(new BorderLayout());

			jContentPane = new JPanel();

			panel1.add(getFileChooser());
			panel1.add(getFileLabel());
			panel1.add(getUploadFile());
			panel1.add(getNewFile());
			panel1.add(getQuery());
			panel1.add(getTextArea());

			panel2.add(new JScrollPane(getSecondTextArea()), BorderLayout.WEST);
			panel2.add(getSpeichern(), BorderLayout.EAST);
			panel2.add(getDelete(), BorderLayout.CENTER);

			jContentPane.setLayout(new BorderLayout());
			jContentPane.add(panel1, BorderLayout.CENTER);
			jContentPane.add(panel2, BorderLayout.SOUTH);

		}
		return jContentPane;
	}

	private void uploadXML(Collection col, File f) throws XMLDBException {

		XMLResource document = (XMLResource) col.createResource(f.getName(),
				XMLResource.RESOURCE_TYPE);
		document.setContent(f);
		col.storeResource(document);
	}

	private Collection openCollection() throws XMLDBException {
		String driver = "org.exist.xmldb.DatabaseImpl";
		String dbURI = "xmldb:exist://" + dburi + "/exist/xmlrpc/db";
		Class cl;
		try {
			cl = Class.forName(driver);

			this.database = (Database) cl.newInstance();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();

		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		DatabaseManager.registerDatabase(database);

		// try to get collection
		// last params are user / password

		Collection col = DatabaseManager.getCollection(dbURI + collection,
				"admin", "aaa");
		if (col == null) {
			final JPasswordField jpf = new JPasswordField();
			JOptionPane jop = new JOptionPane(jpf,
					JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_CANCEL_OPTION);
			JDialog dialog = jop.createDialog("AdminPasswort:");
			dialog.addComponentListener(new ComponentAdapter() {
				@Override
				public void componentShown(ComponentEvent e) {
					SwingUtilities.invokeLater(new Runnable() {
						public void run() {
							jpf.requestFocusInWindow();
						}
					});
				}
			});

			dialog.setVisible(true);
			int result = (Integer) jop.getValue();
			dialog.dispose();
			char[] password = null;
			if (result == JOptionPane.OK_OPTION) {
				password = jpf.getPassword();
			}
			String passwort = new String(password);
			Collection root = DatabaseManager.getCollection(dbURI, "admin",
					passwort);

			CollectionManagementService mgtService = (CollectionManagementService) root
					.getService("CollectionManagementService", "1.0");
			col = mgtService.createCollection(collection);

		}

		return col;
	}

	private void anfrageQuery(String xquery) throws XMLDBException {
		String welcheCollection = "";
		// String dokument = "datei.xml"; // im welchen xml-dokument sollen
		// änderungem gemacht werden
		String URI = "xmldb:exist://localhost:8080" + "/exist/xmlrpc";
		String driver = "org.exist.xmldb.DatabaseImpl";
		Class cl;
		speichern.setEnabled(true);
		try {
			cl = Class.forName(driver);
			Database dbase = (Database) cl.newInstance();
			DatabaseManager.registerDatabase(dbase);

			// -----------------------------------------------------------
			welcheCollection = JOptionPane.showInputDialog(this,
					"Die Collection eingeben:", "xml");

			Collection col = DatabaseManager.getCollection(URI + "/db/"
					+ welcheCollection, "admin", "aaa");

			XPathQueryService xqservice = (XPathQueryService) col.getService(
					"XPathQueryService", "1.0");

			xqservice.setProperty("indent", "yes");

			String newLine = System.getProperty("line.separator");

			ResourceSet result = xqservice.query(xquery); // Resource(dokument,
			ResourceIterator i = result.getIterator();
			while (i.hasMoreResources()) {
				Resource r = i.nextResource();
				System.out.println((String) r.getContent());
				sTa.append((String) r.getContent() + newLine);

			}

		} catch (InstantiationException e) {
			System.out.println(e.getStackTrace());
		} catch (IllegalAccessException f) {
			System.out.println(f.getStackTrace());
		} catch (ClassNotFoundException g) {
			System.out.println(g.getStackTrace());
		}

	}

	public void caretUpdate(CaretEvent event) {
		text = ta.getText();
	}

}